#include "internal.h"
#include "Driver.tmh"

IDriverEntry *Driver::QueryIDriverEntry(VOID) {
    AddRef();
    return static_cast<IDriverEntry*>(this);
}

HRESULT Driver::Initialize(VOID) {
    return S_OK;
}

HRESULT Driver::CreateInstance(__out Driver **resultDriver) {
    Driver *driver;
    HRESULT hr;

    driver = new Driver();

    if (NULL == driver)
        return E_OUTOFMEMORY;

    hr = driver->Initialize();

    if (SUCCEEDED(hr))
        *resultDriver = driver;
    else 
        driver->Release();

    return hr;
}

HRESULT STDMETHODCALLTYPE Driver::OnInitialize(__in IWDFDriver *FxWdfDriver) {
    return S_OK;
}

HRESULT STDMETHODCALLTYPE Driver::OnDeviceAdd(__in IWDFDriver *FxWdfDriver, __in IWDFDeviceInitialize *FxDeviceInit) {
    HRESULT hr;

    Device *device = NULL;

    //
    // TODO: Do any per-device initialization (reading settings from the 
    //       registry for example) that's necessary before creating your 
    //       device callback object here.  Otherwise you can leave such 
    //       initialization to the initialization of the device event 
    //       handler.
    //

    hr = Device::CreateInstance(FxWdfDriver, FxDeviceInit, &device);

    //
    // TODO: Change any per-device settings that the object exposes before
    //       calling Configure to let it complete its initialization.
    //

    if (SUCCEEDED(hr)) 
        hr = device->Configure();

    if (NULL != device)
        device->Release();

    return hr;
}

VOID STDMETHODCALLTYPE Driver::OnDeinitialize(__in IWDFDriver *FxWdfDriver) {
    return;
}

ULONG STDMETHODCALLTYPE Driver::AddRef(VOID) {
    return __super::AddRef();
}

ULONG STDMETHODCALLTYPE Driver::Release(VOID) {
    return __super::Release();
}

HRESULT STDMETHODCALLTYPE Driver::QueryInterface(__in REFIID InterfaceId, __out PVOID *Interface) {
    if (IsEqualIID(InterfaceId, __uuidof(IDriverEntry))) {
        *Interface = QueryIDriverEntry();
        return S_OK;
    }
    else
        return CUnknown::QueryInterface(InterfaceId, Interface);
}
